package com.kx.game.center.utils;

import java.util.HashMap;
import java.util.Set;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;

/**
 * Http工具类
 *
 * @author wenji.fan
 * @since 2013年8月6日
 */
public class HttpUtil {
    private static final String CHARSET = "charset=";
    public static final int DEFAULT_TIMEOUT = 60;

    /**
     * 获取指定地址的内容，如果能够从URLConnection中可以解析出编码则使用解析出的编码，否则就使用GBK编码
     *
     * @param requestUrl
     * @param timeout
     * @param POST
     * @return
     */
    public static String getUrl(String requestUrl, int timeout, boolean POST,
                                String postContent) throws IOException {
        BufferedReader reader = null;
        HttpURLConnection urlConnection = null;
        try {

            if (requestUrl.startsWith("https")) {
                trustAllHosts();
            }
            InputStream urlStream;
            URL url = new URL(requestUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setConnectTimeout(timeout * 1000);
            urlConnection.setReadTimeout(timeout * 1000);
            if (POST) {
                urlConnection.setRequestMethod("POST");
            }

            if (POST && postContent != null) {
                urlConnection.setDoOutput(true);
                OutputStreamWriter writer = new OutputStreamWriter(
                        urlConnection.getOutputStream());
                writer.write(postContent);
                writer.flush();
            } else {
                urlConnection.connect();
            }
            urlStream = urlConnection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(urlStream,
                    parseEncoding(urlConnection)));

            char[] _buff = new char[128];
            StringBuilder temp = new StringBuilder();
            int _len = -1;
            while ((_len = reader.read(_buff)) != -1) {
                temp.append(_buff, 0, _len);
            }
            return temp.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
                urlConnection.disconnect();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    /**
     * 尝试解析出Http请求的编码格式，如果没有解析到则使用GBK编码
     *
     * @param urlConnection
     * @return
     */
    static String parseEncoding(HttpURLConnection urlConnection) {
        String _encoding = urlConnection.getContentEncoding();
        if (_encoding != null) {
            return _encoding;
        }

        String _contentType = urlConnection.getContentType();
        if (_contentType != null) {
            int _index = _contentType.toLowerCase().indexOf(CHARSET);
            if (_index > 0) {
                _encoding = _contentType.substring(_index + CHARSET.length());
            }
        }
        if (_encoding != null) {
            return _encoding;
        } else {
            return "UTF-8";
        }
    }

    /**
     * 信任所有主机-对于任何证书都不做检查
     */
    private static void trustAllHosts() {
        // Create a trust manager that does not validate certificate chains
        // Android 采用X509的证书信息机制
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[]{};
            }

            public void checkClientTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException {
            }

            @Override
            public void checkClientTrusted(
                    java.security.cert.X509Certificate[] chain, String authType)
                    throws java.security.cert.CertificateException {
                // TODO Auto-generated method stub

            }

            @Override
            public void checkServerTrusted(
                    java.security.cert.X509Certificate[] chain, String authType)
                    throws java.security.cert.CertificateException {

            }
        }};

        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection
                    .setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 格式化参数，将参数转化成a=b&c=d&e=f的形式
     *
     * @param parameters
     * @return
     */
    public static String formatParameters(Map<String, String> parameters) {
        StringBuilder sb = new StringBuilder();
        Iterator<Entry<String, String>> iterator = parameters.entrySet()
                .iterator();
        while (iterator.hasNext()) {
            Entry<String, String> entry = iterator.next();
            sb.append(String.format("%s=%s&", entry.getKey(), entry.getValue()));
        }
        if (parameters.size() > 0) {
            return sb.substring(0, sb.length() - 1);
        }
        return sb.toString();
    }

    /**
     * 格式化参数，将参数转化成a=b&c=d&e=f的形式
     *
     * @param parameters
     * @return
     */
    public static String formatInovationParameters(Map<String, String[]> parameters) {
        StringBuilder sb = new StringBuilder();
        Iterator<Entry<String, String[]>> iterator = parameters.entrySet()
                .iterator();
        while (iterator.hasNext()) {
            Entry<String, String[]> entry = iterator.next();
            sb.append(String.format("%s=%s&", entry.getKey(), StringUtils.join(entry.getValue())));
        }
        if (parameters.size() > 0) {
            return sb.substring(0, sb.length() - 1);
        }
        return sb.toString();
    }

    //	private static final String OUT_URL = "http://ss.fruit.feidou.com/center/callback/default";
//	private static final String IN_URL = "http://localhost:8080/game_center_server/callback/default";
//	private static final String IN_URL_HTTPS = "https://localhost:8080/game_center_server/callback/default";
//	private static final String OUT_URL_HTTPS = "https://ss.fruit.feidou.com/center/callback/default";
//	
    public static void main(String[] args) throws Exception {
        BufferedReader _reader = new BufferedReader(new FileReader(new File("D:\\aaa.txt")));
        String publicKey = _reader.readLine();
        publicKey = new String(publicKey.getBytes(), "utf-8");
        System.out.println(publicKey);
        PublicKey _key = publicKey(publicKey);
        System.out.println(_key.getFormat());
        System.out.println(_key.getAlgorithm());
    }
//	
//	public static void test(PlatformType type,String url,String httpsUrl) throws Exception{
//		String _result = "unkown";
//		switch (type) {
//		case ANZHI:
//			_result = getUrl(url+"?pid=4",
//					10000, true, "&amount=6.0&signStr=8018A35D369D1E5F8BC56289603DCD58&payResult=-1&payType=001&pid=4&msg=SUCCESS&ext=MTk5MDpjZjQzYmQ0Ni1mYjc2LTQxZGItYWFkYi04YTc2YzU1MTkwZjU=&orderId=20130831-137858-0441984950022413&appKey=50Si1Js8fLmuKoSpbmG750K3");
//			break;
//		case BAIDU_MOBILE:
//			break;
//		case BAIDU_WEB:
//			break;
//		case DANGLE:
//			_result = getUrl(url+"?pid=5&"+"result=1&time=20130909113045&order=352_637_1_122182239_20130909113032&money=6.00&pid=5&mid=122182239&signature=76e05d015aa65793adb383c50d5bd8c9&ext=2cd1f6b8-c6b1-40fa-a017-3b9afb1901ca",
//					10000, false, "");
//			break;
//		case PPS:
//			break;
//		case QIHU_360:
//			break;
//		case UC:
//			_result = getUrl(url+"?pid=3",
//					10000, true, "{\"sign\":\"1cabff2e94f9d5c83f9ccb57d5294bd4\",\"data\":{\"failedDesc\":\"\",\"amount\":\"50.00\",\"callbackInfo\":\"ab1842ac-c633-4ac6-a691-a7547c1a542a\",\"ucid\":\"200824488\",\"gameId\":\"520452\",\"payWay\":\"301\",\"serverId\":\"2180\",\"orderStatus\":\"S\",\"orderId\":\"201309041716104000918\"}}");
//			break;
//		case WANDOUJIA:
//			_result = getUrl(url+"?pid=7",
//					10000, true, "sign=FJzsFdAZSlbsHHgqTIWzO545HsBD0zMFEvX95zZxL8VIAtTzbt65Sj79qkdPw9vamNlroOm5rsbmvI7vC65gjW9ebWzYZOE9WpW6dowMv6oKFa0fLL%2FdSP5NldTh8AykwuRr12RN%2B37tDaIWGVIqhBwwHmtIzz8Fiz0BCvN1ItE%3D&content=%7B%22orderId%22%3A101542905%2C%22appKeyId%22%3A100000081%2C%22buyerId%22%3A14761017%2C%22cardNo%22%3A%2213565014392212551%22%2C%22money%22%3A600%2C%22chargeType%22%3A%22SHENZHOUPAY%22%2C%22timeStamp%22%3A1378280110900%2C%22out_trade_no%22%3A%22dffae1f4-be82-43c5-a963-c0422eb11e10%22%7D&signType=RSA");
//			break;
//		case XIAOMI:
//			_result = getUrl(url+"?pid=1&uid=8675134&appId=17935&cpOrderId=2fc9910c-8874-46bb-86b7-04624a39c916&productCode=01&pid=1&orderStatus=TRADE_SUCCESS&payTime=2013-08-30 11:37:59&productCount=60&cpUserInfo=8675134&payFee=600&productName=éå¸&orderId=21137783377116436674&signature=dae96bb5c595ccc666fd51aa81a7498c13fa52db",
//					10000, false, "");
//			break;
//		default:
//			break;
//				
//		}
//		System.out.println(_result);
//	}
//	

    private static PublicKey publicKey(String paramString) {
        try {
            byte[] x = Base64.decode(paramString);
            return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(x));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(paramString);
        } catch (java.security.spec.InvalidKeySpecException e) {
            throw new IllegalArgumentException(paramString);
        }
    }

    private static boolean verify(PublicKey paramPublicKey, String paramString1, String paramString2) {
        try {
            Signature localSignature;
            (localSignature = Signature.getInstance("SHA1withRSA")).initVerify(paramPublicKey);
            localSignature.update(paramString1.getBytes());
            if (!localSignature.verify(Base64.decode(paramString2))) {
                return false;
            }
            return true;
        } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
        } catch (InvalidKeyException localInvalidKeyException) {
        } catch (SignatureException localSignatureException) {
        }
        return false;
    }

    /**
     * 解析request的输入流
     *
     * @param request
     * @return 请求的json字符串
     */
    public static synchronized String getRequestBody(HttpServletRequest request) {
        String str = null;
        try {
            str = IOUtils.toString(request.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 解析request为Json
     */
    public static JSONObject getRequestDate(HttpServletRequest request) {
        JSONObject jsonObject = JSONObject.parseObject(getRequestBody(request));
        return jsonObject;
    }


    /**
     * 解析request的json数据
     *
     * @param request
     * @return Map
     */
    public static synchronized Map<String, Object> parseRequest(HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        try {
            String req = getRequestBody(request);
            if (StringUtils.isEmpty(req)) {
                JSONObject jsonObject = JSONObject.parseObject(req);
                for (Entry<String, Object> entry : jsonObject.entrySet()) {
                    map.put(entry.getKey(), entry.getValue());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }


    /**
     * 获取map的value
     *
     * @param map
     * @param key
     * @return
     */
    public static Object getRequestBodyValue(Map<String, Object> map, String key) {
        if (map != null && StringUtils.isEmpty(key) && map.containsKey(key)) {
            return map.get(key);
        }
        return null;
    }
}
